package com.lau.dicttranslator.controller;

import com.lau.dicttranslator.service.DictService;
import com.lau.dicttranslator.util.CacheUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/**
 * 缓存管理控制器
 * 提供缓存操作和监控功能
 */
@RestController
@RequestMapping("/api/cache-management")
public class CacheManagementController {
    
    @Autowired
    private DictService dictService;
    
    @Autowired
    private CacheUtil cacheUtil;
    
    /**
     * 获取缓存统计信息
     */
    @GetMapping("/stats")
    public Map<String, Object> getCacheStats() {
        Map<String, Object> stats = new HashMap<>();

        // 字典缓存统计
        CacheUtil.CacheStats dictStats = cacheUtil.getCacheStats("dict:cache:");
        Map<String, Object> dictCacheStats = new HashMap<>();
        dictCacheStats.put("totalKeys", dictStats.getTotalKeys());
        dictCacheStats.put("activeKeys", dictStats.getActiveKeys());
        dictCacheStats.put("expiredKeys", dictStats.getExpiredKeys());
        dictCacheStats.put("averageExpireTime", dictStats.getAverageExpireTime());
        stats.put("dictCache", dictCacheStats);

        // 枚举缓存统计
        CacheUtil.CacheStats enumStats = cacheUtil.getCacheStats("enum:cache:");
        Map<String, Object> enumCacheStats = new HashMap<>();
        enumCacheStats.put("totalKeys", enumStats.getTotalKeys());
        enumCacheStats.put("activeKeys", enumStats.getActiveKeys());
        enumCacheStats.put("expiredKeys", enumStats.getExpiredKeys());
        enumCacheStats.put("averageExpireTime", enumStats.getAverageExpireTime());
        stats.put("enumCache", enumCacheStats);

        // 总体统计
        Map<String, Object> totalStats = new HashMap<>();
        totalStats.put("dictCacheKeys", dictStats.getTotalKeys());
        totalStats.put("enumCacheKeys", enumStats.getTotalKeys());
        totalStats.put("totalCacheKeys", dictStats.getTotalKeys() + enumStats.getTotalKeys());
        stats.put("total", totalStats);

        return stats;
    }

    /**
     * 清除指定字典类型的缓存
     */
    @DeleteMapping("/dict/{dictType}")
    public Map<String, Object> clearDictCache(@PathVariable String dictType) {
        dictService.clearDictCache(dictType);
        
        Map<String, Object> result = new HashMap<>();
        result.put("success", true);
        result.put("message", "已清除字典缓存: " + dictType);
        result.put("dictType", dictType);
        return result;
    }
    
    /**
     * 清除指定枚举类的缓存
     */
    @DeleteMapping("/enum/{enumClassName}")
    public Map<String, Object> clearEnumCache(@PathVariable String enumClassName) {
        dictService.clearEnumCache(enumClassName);
        
        Map<String, Object> result = new HashMap<>();
        result.put("success", true);
        result.put("message", "已清除枚举缓存: " + enumClassName);
        result.put("enumClassName", enumClassName);
        return result;
    }
    
    /**
     * 清除所有字典相关缓存
     */
    @DeleteMapping("/all")
    public Map<String, Object> clearAllCache() {
        dictService.clearAllCache();
        
        Map<String, Object> result = new HashMap<>();
        result.put("success", true);
        result.put("message", "已清除所有字典相关缓存");
        return result;
    }
    
    /**
     * 获取指定模式的缓存键列表
     */
    @GetMapping("/keys")
    public Map<String, Object> getCacheKeys(@RequestParam(defaultValue = "*") String pattern) {
        Set<String> keys = cacheUtil.keys(pattern);
        
        Map<String, Object> result = new HashMap<>();
        result.put("pattern", pattern);
        result.put("count", keys.size());
        result.put("keys", keys);
        return result;
    }
    
    /**
     * 获取指定缓存键的详细信息
     */
    @GetMapping("/key/{key}")
    public Map<String, Object> getCacheKeyInfo(@PathVariable String key) {
        boolean exists = cacheUtil.exists(key);
        String value = null;
        long expire = -1;
        
        if (exists) {
            value = cacheUtil.get(key);
            expire = cacheUtil.getExpire(key);
        }
        
        Map<String, Object> result = new HashMap<>();
        result.put("key", key);
        result.put("exists", exists);
        result.put("value", value != null ? value : "");
        result.put("expire", expire);
        result.put("expireDesc", getExpireDescription(expire));
        return result;
    }
    
    /**
     * 手动设置缓存
     */
    @PostMapping("/set")
    public Map<String, Object> setCache(@RequestParam String key, 
                                       @RequestParam String value, 
                                       @RequestParam(defaultValue = "3600") long expireSeconds) {
        cacheUtil.set(key, value, expireSeconds);
        
        Map<String, Object> result = new HashMap<>();
        result.put("success", true);
        result.put("message", "缓存设置成功");
        result.put("key", key);
        result.put("value", value);
        result.put("expireSeconds", expireSeconds);
        return result;
    }
    
    /**
     * 删除指定缓存键
     */
    @DeleteMapping("/key/{key}")
    public Map<String, Object> deleteCache(@PathVariable String key) {
        boolean deleted = cacheUtil.delete(key);
        
        Map<String, Object> result = new HashMap<>();
        result.put("success", deleted);
        result.put("message", deleted ? "缓存删除成功" : "缓存删除失败或不存在");
        result.put("key", key);
        return result;
    }
    
    /**
     * 测试不同过期时间的缓存
     */
    @PostMapping("/test-expire")
    public Map<String, Object> testCacheExpire() {
        String baseKey = "test:expire:";
        
        // 设置不同过期时间的测试缓存
        cacheUtil.set(baseKey + "10s", "10秒后过期", 10);
        cacheUtil.set(baseKey + "30s", "30秒后过期", 30);
        cacheUtil.set(baseKey + "60s", "60秒后过期", 60);
        cacheUtil.set(baseKey + "never", "永不过期");
        
        Map<String, Object> testKeys = new HashMap<>();
        testKeys.put("10s", baseKey + "10s");
        testKeys.put("30s", baseKey + "30s");
        testKeys.put("60s", baseKey + "60s");
        testKeys.put("never", baseKey + "never");
        
        Map<String, Object> result = new HashMap<>();
        result.put("success", true);
        result.put("message", "测试缓存已设置");
        result.put("testKeys", testKeys);
        return result;
    }
    
    /**
     * 预热缓存 - 预加载常用字典数据
     */
    @PostMapping("/warmup")
    public Map<String, Object> warmupCache() {
        int warmedUp = 0;
        
        // 预热性别字典
        try {
            dictService.getDictLabel("gender", "M", true, 7200);
            dictService.getDictLabel("gender", "F", true, 7200);
            warmedUp += 2;
        } catch (Exception e) {
            // 忽略错误
        }
        
        // 预热部门字典
        try {
            dictService.getDictLabel("department", "001", true, 3600);
            dictService.getDictLabel("department", "002", true, 3600);
            dictService.getDictLabel("department", "003", true, 3600);
            warmedUp += 3;
        } catch (Exception e) {
            // 忽略错误
        }
        
        // 预热状态枚举
        try {
            dictService.getEnumLabel("com.lau.dicttranslator.enums.StatusEnum", "1", true, 86400);
            dictService.getEnumLabel("com.lau.dicttranslator.enums.StatusEnum", "0", true, 86400);
            warmedUp += 2;
        } catch (Exception e) {
            // 忽略错误
        }
        
        Map<String, Object> result = new HashMap<>();
        result.put("success", true);
        result.put("message", "缓存预热完成");
        result.put("warmedUpCount", warmedUp);
        return result;
    }
    
    /**
     * 获取过期时间描述
     */
    private String getExpireDescription(long expire) {
        if (expire == -1) {
            return "永不过期";
        } else if (expire == -2) {
            return "键不存在";
        } else if (expire == 0) {
            return "已过期";
        } else if (expire < 60) {
            return expire + "秒后过期";
        } else if (expire < 3600) {
            return (expire / 60) + "分钟后过期";
        } else if (expire < 86400) {
            return (expire / 3600) + "小时后过期";
        } else {
            return (expire / 86400) + "天后过期";
        }
    }
} 